package com.xiao.task;

import com.xiao.controller.ThreadPoolController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

/**
 * @author QuanZhao.Xiao
 * @description
 * @date 2022/1/24 18:59:15
 */
@Component
@Slf4j
public class ThreadPoolTask {


    /**
     * 定时记录线程池状态
     */
    @Scheduled(cron = "0/1 * * * * ?")
    public void doTask() {
        //take some log for ThreadPool ...
        int corePoolSize = ThreadPoolController.poolExecutor.getCorePoolSize();
        int maximumPoolSize = ThreadPoolController.poolExecutor.getMaximumPoolSize();
        long taskCount = ThreadPoolController.poolExecutor.getTaskCount();
        long completedTaskCount = ThreadPoolController.poolExecutor.getCompletedTaskCount();
        String queueName = ThreadPoolController.poolExecutor.getQueue().getClass().getSimpleName();
        int queueSize = ThreadPoolController.poolExecutor.getQueue().size();
        int poolSize = ThreadPoolController.poolExecutor.getPoolSize();
        int activeCount = ThreadPoolController.poolExecutor.getActiveCount();
        int largestPoolSize = ThreadPoolController.poolExecutor.getLargestPoolSize();
        log.info("核心线程数：" + corePoolSize);
        log.info("最大线程数：" + maximumPoolSize);
        log.info("总任务数：" + taskCount);
        log.info("已完成任务数：" + completedTaskCount);
        log.info("队列类型：" + queueName);
        log.info("队列任务数：" + queueSize);
        log.info("当前线程数：" + poolSize);
        log.info("活跃线程数：" + activeCount);
        log.info("pool中线程最高使用数量：" + largestPoolSize);
        //线程池资源利用率
        log.info("资源利用率：" + getThreadUsedRate(activeCount, maximumPoolSize));
        log.info("-----------");
    }

    /**
     * 线程池资源利用率 = (活跃线程数 * 100 / 最大线程数) * 100%
     * @param activeCount
     * @param maximumPoolSize
     * @return
     */
    private String getThreadUsedRate(int activeCount, int maximumPoolSize) {
        BigDecimal ac = new BigDecimal(activeCount);
        BigDecimal mps = new BigDecimal(maximumPoolSize);
        return ac.multiply(new BigDecimal(100)).divide(mps, 2, BigDecimal.ROUND_HALF_UP) + "%";
    }

}